#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include<assert.h>
#include<string.h>

#define Num 1024
char LineCommand[Num];
#define opt 64
char *OptArray[opt];//指针数组

int ExitCode=0;
int SigCode=0;

int main()
{

  while(1)
  {
  printf("用户名@路径 我的路径 ");
  fflush(stdout);
  //首先获取从键盘上获取字符,在输入的时候，自己会输入\n
  char* s=fgets(LineCommand,sizeof(LineCommand)-1,stdin);
  assert(s!=NULL);
  (void)s;
  LineCommand[strlen(LineCommand)-1]=0; //去掉尾部的\n
 // printf("%s\n",LineCommand);
 //拆解获取的字符
 OptArray[0]=strtok(LineCommand," ");
 //printf("%s\n",OptArray[0]); 
 int j=1;
 //在ls查看时，给文件带上颜色
 if(OptArray[0] !=NULL && strcmp(OptArray[0],"ls")==0)
 {
    OptArray[j++]=(char*)"--color=auto";
 }

 while(OptArray[j++]=strtok(NULL ," "));
  //在使用cd ..的时候，需要切换的是父进程的工作目录，而不是执行完操作后的子进程操作
  //所以这里需要使用chdir
  
 if(OptArray[0]!=NULL && strcmp(OptArray[0],"cd")==0)
 {
   chdir(OptArray[1]);
   continue;
 }

//像这种只有父进程执行，子进程没有执行的，称之为内置/内建型语言
//echo 也是内置/内建型
 if(OptArray[0]!=NULL && strcmp(OptArray[0],"echo")==0)
 {
    if(strcmp(OptArray[1],"$?")==0)
    {
      printf("%d   %d\n",ExitCode,SigCode);
    }
    else 
    {
      printf("%s\n",OptArray[1]);
    }
    continue; 
 }

 /*
#ifdef  DDEBUG 
  for(int i=0;OptArray[i];++i)
  {
    printf("OptArray[%d]:%s\n",i,OptArray[i]);
  }
#endif
  */
  //分割完成之后，需要创建一个子进程
  //子进程需要进程替换
  pid_t id = fork();
  assert(id!=-1);
  if(id==0)
  {
    execvp(OptArray[0],OptArray);
    exit(1);
  }
  int status=0;
  waitpid(id,&status,0);
  ExitCode = (status>>8)&0xff;
  SigCode = status&0x7f;
  }
  return 0;
}
